home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / XPK / elzx / xpkELZX.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-04  |  7.3 KB  |  279 lines

  1. /*
  2.  * This library is mainly intended to demonstrate how to program a sub
  3.  * library.
  4.  *
  5.  * Now it's a serious sub-library.  ;)
  6.  *
  7.  * v1.1  Modified by Daniel J. Andrea II to fix a bug in picking the filename
  8.  *        out of the LZX archive.  Also changed to using the address of the 
  9.  *        input buffer instead of ExecBase->ThisTask for the filenames.  The
  10.  *        old method ALWAYS gave back the same address, irregardless of who was
  11.  *        using the sublibrary.  Using the input buffer address should produce
  12.  *        a unique value so multiple invocations of the library won't walk all
  13.  *        over it's own data.  Unpacking data packed with the old version will
  14.  *        still work because the name of the file stored in the LZX archive is
  15.  *        pulled straight out of the archive itself, though multiple simultaneous
  16.  *        invocations of older packed data may still walk all over it's own data
  17.  *        from other invocations.  Changed some of the DEFINE values to make
  18.  *        source all English and removed sections referring to conditional
  19.  *        compilation if Z_PIPE was defined (I never used this anyways since LZX
  20.  *        doesn't work properly with pipes).  Also added some debug stuff to have
  21.  *        LZX redirect it's output to a file in T:, add 'DEFINE=LZXDEBUG' to the
  22.  *        CMFLAGS section of the SMakefile to enable.
  23.  *
  24.  $VER: xpk LZX libs 1.1 (04-Sept-97) © 1997 Daniel J. Andrea II
  25.  */
  26.  
  27. #define NO_SUB_PRAGMAS
  28. #define MaksymalnyC 0x80000
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <libraries/xpksub.h>
  33. #include <proto/dos.h>
  34. #include <proto/exec.h>
  35. #include <dos/dos.h>
  36. #include <dos/dostags.h>
  37. #include <exec/exec.h>
  38.  
  39. #define A3000 XPKMF_A3000SPEED
  40.  
  41. XMINFO RlenMode4 = {
  42.     NULL,        // next
  43.     100,         // upto
  44.     A3000,       // flags
  45.     0,           // packmem
  46.     0,           // unpackmem
  47.     30,         // packspeed,   K/sec
  48.     150,        // unpackspeed, K/sec
  49.     500,          // ratio,      *0.1%
  50.     0,           // reserved
  51.     "best"         // description
  52. };
  53. XMINFO RlenMode3 = {
  54.     &RlenMode4,  // next
  55.     80,         // upto
  56.     A3000,       // flags
  57.     0,           // packmem
  58.     0,           // unpackmem
  59.     31,         // packspeed,   K/sec
  60.     150,        // unpackspeed, K/sec
  61.     480,          // ratio,      *0.1%
  62.     0,           // reserved
  63.     "better"     // description
  64. };
  65. XMINFO RlenMode2 = {
  66.     &RlenMode3,  // next
  67.     60,         // upto
  68.     A3000,       // flags
  69.     0,           // packmem
  70.     0,           // unpackmem
  71.     32,         // packspeed,   K/sec
  72.     150,        // unpackspeed, K/sec
  73.     460,          // ratio,      *0.1%
  74.     0,           // reserved
  75.     "good"         // description
  76. };
  77. XMINFO RlenMode1 = {
  78.     &RlenMode2,  // next
  79.     40,         // upto
  80.     A3000,       // flags
  81.     0,           // packmem
  82.     0,           // unpackmem
  83.     33,         // packspeed,   K/sec
  84.     150,        // unpackspeed, K/sec
  85.     440,          // ratio,      *0.1%
  86.     0,           // reserved
  87.     "poor"         // description
  88. };
  89. XMINFO RlenMode = {
  90.     &RlenMode1,    // next
  91.     20,         // upto
  92.     A3000,       // flags
  93.     0,           // packmem
  94.     0,           // unpackmem
  95.     34,         // packspeed,   K/sec
  96.     150,        // unpackspeed, K/sec
  97.     10,          // ratio,      *0.1%
  98.     0,           // reserved
  99.     "none"         // description
  100. };
  101. #ifndef DEMOLZX
  102. char *mody="012339";
  103. #else
  104. char *mody="012333";
  105. #endif
  106. static struct XpkInfo RlenInfo = {
  107.         1,               /* info version */
  108.         0,               /* lib  version */
  109.         0,               /* master vers  */
  110.         0,               /* pad          */
  111. #ifndef CODE_DELTA
  112.         "ELZX",          /* short name   */
  113.         "External LZX  ",/* long name    */
  114.         "very good compression library      middle speed   ", /* description*/
  115.         'ELZX',          /* 4 letter ID  */
  116. #else
  117.         "SLZX",          /* short name   */
  118.         "LZX with delta",/* long name    */
  119.         "External LZX compression for samples and mods     ", /* description*/
  120.         'SLZX',          /* 4 letter ID  */
  121. #endif
  122.         XPKIF_PK_CHUNK | /* flags        */
  123.         XPKIF_UP_CHUNK |
  124.         XPKIF_MODES,
  125.         MaksymalnyC,     /* max in chunk */
  126.         1,               /* min in chunk */
  127.         MaksymalnyC,     /* def in chunk */
  128.         NULL,            /* pk message   */
  129.         NULL,            /* up message   */
  130.         NULL,            /* pk past msg  */
  131.         NULL,            /* up past msg  */
  132.         80,              /* def mode     */
  133.         0,               /* pad          */
  134.         &RlenMode        /* modes        */
  135. };
  136.  
  137. /*
  138.  * Returns an info structure about our packer
  139.  */
  140. struct XpkInfo * __saveds __asm
  141. XpksPackerInfo( void )
  142. {
  143.     return &RlenInfo;
  144. }
  145.  
  146.  
  147. void __saveds __asm
  148. XpksPackFree( REG __a0 XPARAMS* xpar )
  149. {
  150. }
  151.  
  152. /*
  153.  * This forces the next chunk to be uncompressable independent from the
  154.  * previous one. This is always the case in RLEN.
  155.  */
  156. long __saveds __asm
  157. XpksPackReset( REG __a0 XPARAMS* xpar )
  158. {
  159.     return 0;
  160. }
  161.  
  162.  
  163. void __saveds __asm
  164. XpksUnpackFree( REG __a0 XPARAMS* xpar )
  165. {
  166. }
  167. /*
  168.  * Pack a chunk
  169.  */
  170. long __saveds __asm
  171. XpksPackChunk( REG __a0 XPARAMS *xpar )
  172. {
  173.     UBYTE *get =xpar->InBuf,*put=xpar->OutBuf;
  174. #ifdef CODE_DELTA
  175.     UBYTE *docel=xpar->OutBuf;
  176.     int   i;
  177. #endif
  178.  
  179. // Moje dodatki
  180.     char temp1[100],temp2[100],sysus[100];
  181.     struct Library *DOSBase;
  182.     BPTR tmp; 
  183.  
  184.     DOSBase=OpenLibrary("dos.library",37);
  185.     sprintf(temp1,"t:ltf%x",get);
  186.     sprintf(temp2,"t:ltf%x.lzx",get);
  187. #ifndef DEMOLZX
  188. #ifdef LZXDEBUG
  189.     sprintf(sysus,"lzx -Qf -%c a <nil: >>T:XPKLZXDEBUG.log %s %s",mody[((xpar->Mode|1)-1)/20],temp2,temp1);
  190. #else
  191.     sprintf(sysus,"lzx -Qf -%c a <>nil: %s %s",mody[((xpar->Mode|1)-1)/20],temp2,temp1);
  192. #endif
  193. #else
  194. #ifdef LZXDEBUG
  195.     sprintf(sysus,"lzx -%c a <nil: >>T:XPKLZXDEBUG.log %s %s",mody[((xpar->Mode|1)-1)/20],temp2,temp1);
  196. #else
  197.     sprintf(sysus,"lzx -%c a <>nil: %s %s",mody[((xpar->Mode|1)-1)/20],temp2,temp1);
  198. #endif
  199. #endif
  200.     DeleteFile(temp2);
  201.     tmp=Open(temp1,MODE_NEWFILE);
  202. #ifdef CODE_DELTA
  203.     for(i=0;docel<put+xpar->InLen;*docel++=*get-i,i=*get++) {};
  204.     Write(tmp,put,xpar->InLen);
  205. #else
  206.     Write(tmp,get,xpar->InLen);
  207. #endif
  208.     Close(tmp);
  209.     SystemTagList(sysus,(void *)0);
  210.     tmp=Open(temp2,MODE_OLDFILE);
  211.     Seek(tmp,0,OFFSET_END);
  212.     if ( Seek(tmp,0,OFFSET_BEGINNING) < MaksymalnyC )
  213.         xpar->OutLen=Read(tmp,put,MaksymalnyC);
  214.      else
  215. #ifndef CODE_DELTA
  216.         CopyMem(get,put,xpar->OutLen=xpar->InLen);
  217. #else
  218.         xpar->OutLen=MaksymalnyC;
  219. #endif
  220.     Close(tmp);
  221.     DeleteFile(temp1);
  222.     DeleteFile(temp2);
  223.     CloseLibrary(DOSBase);
  224.     return 0;
  225. }
  226.  
  227. long __saveds __asm
  228. XpksUnpackChunk( REG __a0 XPARAMS* xpar )
  229. {
  230.     char *get=xpar->InBuf, *put=xpar->OutBuf;
  231. #ifdef CODE_DELTA
  232.     int        x,i;
  233. #endif
  234.     char temp1[100],temp2[100],sysus[100],nmln;
  235.     struct Library *DOSBase;
  236.     BPTR tmp;
  237.  
  238.     if ( MaksymalnyC == xpar->InLen ) 
  239. #ifndef CODE_DELTA
  240.         CopyMem(get,put,MaksymalnyC);
  241. #else
  242.         for(x=0,i=MaksymalnyC;i--;*put+=x,x=*put++);
  243. #endif
  244.      else {
  245.         DOSBase=OpenLibrary("dos.library",37);
  246.         strcpy(temp1,"t:");
  247.     
  248.     /* The following two lines of code had a bug in the original version.
  249.        It assumed a set length for the file name inside the archive.  
  250.        The byte at offset 0x28 is the length of the filename, so that is
  251.        now used instead.    DJA, 04-Sept-97 v1.01  */
  252.     
  253.     nmln=get[0x28];
  254.         strncat(temp1,get+0x29,nmln);
  255.         sprintf(temp2,"t:ltf%0x.lzx",get);
  256.         tmp=Open(temp2,MODE_NEWFILE);
  257.         Write(tmp,get,xpar->InLen);
  258.         Close(tmp);
  259. #ifdef LZXDEBUG
  260.         sprintf(sysus,"lzx x <nil: >>T:XPKLZXDEBUG.log %s t:",temp2);
  261. #else
  262.         sprintf(sysus,"lzx x <>nil: %s t:",temp2);
  263. #endif
  264.         SystemTagList(sysus,(void *)0);
  265.         tmp=Open(temp1,MODE_OLDFILE);
  266. #ifdef CODE_DELTA
  267.         i=Read(tmp,put,MaksymalnyC);
  268.         for(x=0;i--;*put+=x,x=*put++){};
  269. #else
  270.         Read(tmp,put,MaksymalnyC);
  271. #endif
  272.         Close(tmp);
  273.         DeleteFile(temp1);
  274.         DeleteFile(temp2);
  275.         CloseLibrary(DOSBase);
  276.     }
  277.     return 0;
  278. }
  279.